// api
import{ deletePlanTask, getPlanTaskList, getPlanTaskListInitData, getCurrentAllTaskTypeList } from '@src/api/TaskApi'
/* business */
import BizListView from '@src/component/business/BizListView/BizListView.tsx'
import BizListViewTask from '@src/component/business/BizListView/Impl/BizListViewTask/BizListViewTask.tsx'
import PropagandaPage from '@src/component/compomentV2/PropagandaPage';
import UpgradeToSmartPlanDialog from '@src/modules/task/taskTypes/planTask/components/UpgradeToSmartPlanDialog'
/* enum */
import ComponentNameEnum from '@model/enum/ComponentNameEnum'
import StorageKeyEnum from '@model/enum/StorageKeyEnum'
import AuthEnum from '@model/enum/AuthEnum'
import { smartPlanUpgrade } from '@model/enum/PropaganPageEnum'
/* entity */
import { PlanTask, TaskStatus } from '@model/entity/PlanTask'
import Field from '@model/entity/Field'
import TaskType from '@model/entity/TaskType'
/* model */
import { getTaskPlanTaskInitDataResult, getTaskPlanTaskResult, getTaskPlanTaskDetailResult } from '@model/param/out/Task'
import { getColumnFields, getAdvancedFields, getTaskStatusFields } from '@src/modules/task/taskTypes/planTask/fields'
import { CONFIRM_DELETE_PLAN_TASK_MESSAGE, DELETE_SUCCESS_MESSAGE, NOT_OPEN_PLANTASK_MASSAGE, PLEASE_SELECT_DATA_MESSAGE } from '@src/model/const/Alert'
import Column from '@model/types/Column'
import Page from '@model/Page.js'
import { commonUseItemType } from '@src/component/AdvancedSearch/advancedSearch'
/* scss */
import '@src/modules/task/taskTypes/planTask/TaskPlanTaskList.scss'
/* types */
import ElementColumn from '@model/types/ElementColumn'
/* vue */
import { Component } from 'vue-property-decorator'
import { CreateElement, VNode } from 'vue'
/* util */
import { strConcat, uuid } from 'pub-bbx-utils'
import { getRootWindow } from '@src/util/dom';
import { isEnterpriseEdition, hasBSCEnterpriseEdition } from '@src/util/version'
import { openTabForPlanTaskCreate } from '@src/util/business/openTab'
import Platform from '@src/util/platform'
import LogUtil from '@src/util/log.ts'
import EsTask from '@model/entity/EsTask'
import AuthUtil from '@src/util/auth'
import { stringify } from '@src/util/lang/object'
import { checkButtonDisplayed } from '@src/util/dom';
import * as _ from 'lodash';
import i18n from '@src/locales'

/* export & import */
import { taskPlanTaskListExport } from '@src/api/Export';
// import { eventListImport_1, eventListImportTem_1 } from '@src/api/Import';

import { storageSet, storageGet } from '@src/util/storageV2';

@Component({ 
  name: ComponentNameEnum.TaskPlanTaskList,
  components: {
    [PropagandaPage.name]: PropagandaPage,
    [UpgradeToSmartPlanDialog.name]: UpgradeToSmartPlanDialog,
  }
})
export default class TaskPlanTaskList<T = PlanTask, P = Page> extends BizListViewTask<T, P> {
  
  public advancedColumnNumberKey: StorageKeyEnum = StorageKeyEnum.TaskPlanTaskAdvancedColumnNum
  /* 列表导出缓存 */
  public exportStorageKey: StorageKeyEnum = StorageKeyEnum.TaskPlanTaskExport
  /* 已选择面板列 */
  public baseSelectionPanelColumns: ElementColumn[] = [{ label: i18n.t('common.fields.taskName.displayName') as string, prop: 'name'}, { label: i18n.t('common.task.taskType') as string, prop: 'templateName' }]
  /* 列数据 */
  public columns: Column[] = this.getColumnFields(this) as Column[]
  /* 导出地址url */
  public exportActionUrl: string = taskPlanTaskListExport
  /* 导出文件名 */
  public exportFileName: string = i18n.t('task.taskTypes.planTask.planTaskData') as string
  /* 是否为表单模式导出下载 */
  public isExportDownloadFormMode: boolean = true
  /* 初始数据 */
  public initData: getTaskPlanTaskInitDataResult = {
    tagTaskTypeList: [],
    planTaskOn: true,
    taskTypeList: []
  }
  /* 无权限提示文字 */
  private noPermissionText: string = NOT_OPEN_PLANTASK_MASSAGE
  /* 计划任务搜索参数 */
  private planTaskSearchModel: Record<string, any> = {}
  /* 选择列 缓存键名 */
  public selectColumnStorageKey: StorageKeyEnum = StorageKeyEnum.TaskPlanTaskTableColumns
  /* pageSize 缓存键名 */
  public pageSizeStorageKey: StorageKeyEnum = StorageKeyEnum.TaskPlanTaskPageSize
  /* 任务状态 */
  public taskStatus: TaskStatus[] = getTaskStatusFields() as TaskStatus[]
  /* 当前任务状态 */
  public currentTaskStatus: TaskStatus = { id: null }
  /* 工单类型列表 */
  public taskTypes: TaskType[] = []
  /* 工单读类型列表 */
  public readTypeList: TaskType[] = []
  
  get globalLoginUserAuth() {
    return (this.rootWindowInitData?.user?.auth || {})
  }
  
  /**
   * @description: 是否允许创建计划任务
   * -- 拥有新建工单权限和工单派单权限
   * @return {boolean}
   */
  get allowCreatePlanTask(): boolean {
    return AuthUtil.hasEveryAuth(this.auth, [AuthEnum.TASK_ADD, AuthEnum.TASK_DISPATCH, AuthEnum.VIP_TASK_PLAN])
  }
  
    /**
   * @description: 是否允许查看计划任务详情
   * @return {boolean}
   */
  get allowViewPlanTaskDetail(): boolean {
    return AuthUtil.hasEveryAuth(this.globalLoginUserAuth, [AuthEnum.TASK_PLAN_VIEW_DETAIL])
  }
  
  /**
   * @description: 是否允许导出
   * @return {boolean}
   */
  get allowExport(): boolean {
    return Boolean(this.auth?.[AuthEnum.TASK_PLAN_EXPORT])
  }
  
  /**
   * @description: 是否允许删除计划任务
   * @return {boolean}
   */
  get allowDelete(): boolean {
    return Boolean(this.auth?.[AuthEnum.TASK_PLAN_DELETE])
  }
  
  /**
   * @description: 计划任务是否开启 
   * @return {Boolean} 计划任务开启状态
   */  
  get planTaskOn(): boolean {
    return Boolean(this.initData.planTaskOn)
  }
  
  get BizListViewInstance(): BizListView<PlanTask, Page> {
    return new BizListView()
  }

  /**
   * @description: 是否为华大基因
   * @return {boolean}
   */
  get isBgiSaas(): boolean {
    const RootWindow = getRootWindow(window)
    return Boolean(RootWindow.grayAuth?.bgiSaas)
  }

  /**
   * @description: 智能计划灰度
   * @return {boolean}
   */
   get smartPlanGray(): boolean {
    const RootWindow = getRootWindow(window)
    return Boolean(RootWindow.grayAuth?.SMART_PLAN)
  }
  
  /**
   * @description 构建导出参数
   * @param {string[]} checkedArray 选择的导出列key
   * @param {string[]} ids 选择的id列表
   * @param {Boolean} exportOneRow 多选类型的字段在导出时，不同值在同一个单元格中显示（例如：字段名称：1/2/3/4）
   * @return {Record} 导出参数
   */
  public buildExportParams(checkedArray: unknown, ids: string[]): any {
    const params = {
      ...this.searchParams,
      ...this.buildAdvancedSearchParams(), // 采用旧的高级搜索（只有常用条件）
    }
    this.planTaskSearchModel = params
    return {
      data: strConcat(ids),
      planTaskSearchModel: stringify(this.planTaskSearchModel),
      checked: checkedArray
    }
  }
  
  /**
   * @description: 创建计划任务
   * @param {TaskType} taskType 工单类型
   * @return {void}
   */  
  private createPlanTask(taskType: TaskType): void {
    // @ts-ignore
    this.$track.clickStat(this.$track.formatParams('TO_CREATE'));
    openTabForPlanTaskCreate(taskType.id)
  }
  
  /**
   * @description: 删除事件
   * @return {Promise<boolean | void>}
   */  
  public async deleteHandler(): Promise<boolean | void> {
    const validated = this.selectedTaskDataValidate()
    if (!validated) return
    
    try {
      const confirm = await Platform.confirm(CONFIRM_DELETE_PLAN_TASK_MESSAGE)
      if (!confirm) return
      
      this.loading = true
      
      const params = { ids: this.selectedIds || [] }
      const result = await deletePlanTask(params) || {}
      const success = result.success
      if (!success) {
        return Platform.alert(result?.message || '')
      }
      
      Platform.alert(DELETE_SUCCESS_MESSAGE)
      
      this.BizTableComponent?.outsideClearSelection()
      this.multipleSelection = []
      this.search()
      
    } catch (error) {
      LogUtil.error(error, this.deleteHandler.name)
    } finally {
      this.loading = false
    }
  }
  
  /**
   * @description: 获取高级搜索字段列表
   * @param {BizListView} vm 当前实例
   * @return {Field[]} 高级搜索字段列表
   */  
  public getAdvancedFields(vm: BizListView<EsTask, Page>): Field[] {
    return getAdvancedFields(vm)
  }
  
  /**
   * @description: 获取表格列字段列表
   * @param {BizListView} vm 当前实例
   * @return {Field[]} 表格列字段列表
   */  
  public getColumnFields(vm: BizListView<EsTask, Page>): Field[] {
    return getColumnFields(vm,'plan')
  }
  
  /** 
   * @description 获取属性
  */
  public getAttributes() {
    const classNames: string[] = [ComponentNameEnum.TaskPlanTaskList, 'common-list-container__v2']
    
    return {
      class: classNames,
      directives: [
        // {
        //   name: 'loading',
        //   value: this.loading
        // }
      ]
    }
  }
  
  /**
   * @description 获取表格列表数据
   * @return {void}
   */  
  public fetchTableListData(): void {
    
    const params = {
      ...this.searchParams,
      ...this.buildAdvancedSearchParams(), // 采用旧的高级搜索（只有常用条件）
    }
    
    this.planTaskSearchModel = params
    this.fetchPlanTaskTaskList(params)
  }
  
  /**
   * @description 获取计划任务列表数据
   * @param {Record} searchParams 搜索参数
   * @return {void}
   */  
  private fetchPlanTaskTaskList(searchParams: Record<string, any> = {}): void {
    // 未开启计划任务
    if (!this.planTaskOn) {
      this.loading = false
      return
    }
    
    let params = {
      ...this.searchParams,
      ...searchParams
    }
    
    this.loading = true
    
    getPlanTaskList(params)
      .then((data: getTaskPlanTaskResult) => {
        
        if (!data?.success) {
          return Platform.alert(data?.message || '')
        }
        
        this.planTaskSetTemplateNameHandler(data)
        
        this.page = new Page(data?.result) || {}
      })
      .catch(err => {
        console.error(err)
      })
      .finally(() => {
        this.loading = false
      })
  }
  
  /**
   * @description: 获取初始化数据
   * @return {Promise<void>}
   */  
  public async fetchInitData(): Promise<void> {
    this.loading = true
    
    return (
      getPlanTaskListInitData()
      .then((result) => {
        const data = result.result || {}
        this.initData = data 
        this.taskTypes = data.tagTaskTypeList || []
        this.readTypeList = data.taskTypeList || []
        this.auth = data?.authorities || {}
      })
      .catch(err => {
        console.error(err)
      })
    )
  }
  
  /**
   * @description: 打开导出面板
   * @param {string} exportIds 导出的ids列表
   * @param {string} fieldName 导出的文件名
   * @return {void}
   */  
  public openExportPanel(exportIds: string[], fieldName: string): void {
    // @ts-ignore
    this.BaseExportComponent?.open(exportIds, fieldName, true)
  }
  
  /**
   * @description 计划任务设置工单类型名称处理
   * !! 注意 此方法会改变原始数据
   * @param {getTaskPlanTaskResult} data 计划任务列表数据
   * @return {void}
   */  
  private planTaskSetTemplateNameHandler(data: getTaskPlanTaskResult): void {
    if (!data?.result?.list) return
    
    const planTaskList: PlanTask[] = data.result.list as PlanTask[]
    
    data.result.list = planTaskList.map((planTask: PlanTask) => {
      planTask.templateName = planTask?.task?.templateName
      return planTask
    })
    
  }
  
  /**
   * @description: 构建高级搜索面板参数
   * @return {Record<string, any>}
   */  
  public buildAdvancedSearchParams(): Record<string, any> {
    
    // 获取高级搜索参数
    const advancedSearchParams = this.BaseSearchPanelComponent?.buildParams() || {}
    
    LogUtil.info(advancedSearchParams, this.buildAdvancedSearchParams.name, this.buildAdvancedSearchParams.name)
    
    // 存在工单类型数据
    if (advancedSearchParams.templateId) {
      
      const typeId: string = advancedSearchParams.templateId
      const taskType: TaskType | undefined = this.taskTypes.find(item => item.templateId === typeId)
      
      // 更新当前工单类型新
      this.currentTaskType = {
        id: typeId,
        templateId: typeId,
        name: taskType?.name || ''
      }
      
    } 
    
    return advancedSearchParams
  }

  /**
   * @description: 搜索
   * @return {void}
   */
  public search(): void {//计划任务的搜索
    
    LogUtil.succ(LogUtil.Start, this.search.name)
    
    this.fetchTableListData()
  }
  
  /**
   * @description: 选择数据验证
   * @return {boolean}
   */  
  public selectedTaskDataValidate(selectedIds: string[] = []): boolean {
    let validated = true
    // 未选择数据错误提示
    if (!this.selectedIds.length && !selectedIds.length) {
      validated = false
      Platform.alert(PLEASE_SELECT_DATA_MESSAGE)
    }
    return validated
  }
  
  /**
   * @description: 切换高级搜索面板
   * @param {boolean} toggle 切换的状态
   * @return {void}
   */  
  public toggleAdvancedSearchPanel(toggle: boolean = true): void {
    return this.BizListViewInstance.toggleAdvancedSearchPanel.call(this, toggle)
  }
  
  /**
   * @description: 渲染高级搜索面板
   * @return {VNode}
   */ 
  public renderAdvancedSearchPanel(): VNode {
    return this.BizListViewInstance.renderAdvancedSearchPanel.call(this)
  }
  
  /**
   * @description: 渲染新建计划任务下拉菜单
   * @return {VNode | null} 元素或者空
   */  
  public renderCreatePlanTaskDropdown(): VNode | null {    
    const DropdownMenuComponent = (
      <el-dropdown-menu>
        {
          this.taskTypes.map((taskType: TaskType) => {
            return (
              <el-dropdown-item key={uuid()}>
                <div onClick={() => this.createPlanTask(taskType)}>
                  { taskType.name }
                </div>
              </el-dropdown-item>
            )
          })
        }
      </el-dropdown-menu>
    )
    
    return (
      <el-dropdown>
        <el-button type='primary' icon='el-icon-plus'>
          {i18n.t('common.base.create')}
        </el-button>
        <div slot='dropdown'>
          { DropdownMenuComponent }
        </div>
      </el-dropdown>
    )
  }
  
  /**
   * @description: 渲染操作区域容器
   * @return {VNode}
   */ 
  public renderOperationContainer(): VNode {
    return (
      <div ref="tableDoContainer" class='common-list-view__v2 mt_12 operation-container pad-b-none'>
        <div class='common-list-view-header__v2 task-ai'>
          <div class='common-list-view-header__v2-left task-ai'>
            { this.allowCreatePlanTask && this.renderCreatePlanTaskDropdown() }
            { this.renderDeleteButton() }
          </div>
          <div class='common-list-view-header__v2-right task-ai'>
            {/* 企业版或者服务云企业版显示 */}
            { (isEnterpriseEdition() || hasBSCEnterpriseEdition()) && (<propaganda-page onShowUpgradeToSmartPlanDialog={this.showUpgradeToSmartPlanDialog} propagandaData={smartPlanUpgrade}></propaganda-page>)}
            { checkButtonDisplayed() && (this.renderMoreActionDropdown()) }
            { this.renderSelectColumnsButton() }
          </div>
        </div>
      </div>
    )
  }

  public showUpgradeToSmartPlanDialog() {
    this.$refs.upgradeToSmartPlanDialog.openDialog()
  }
  public computedListPxArray(){
    let padding = [24, 16, 16]
    return padding;
  }
  public changePackUpLocal(){
    this.changePackUp()
  }
  
  async mounted() {
    // 恢复常用
    this.recoverCommonUse();
    // 合并本地缓存列数据至当前实例的列数据
    this.mergeLocalStorageColumnsToColumns()
    // 获取初始化数据
    await this.fetchInitData()
    // 获取工单计划任务列表
    this.fetchPlanTaskTaskList()
    /* 搜索placeholder */
    this.searchPlaceholder = i18n.t('task.tip.planTaskTip10') as string;
    // [tab_spec]标准化刷新方式
    window.__exports__refresh = async () => {
      setTimeout(() => {
        this.search()
      }, 1000)
    }
    let that_ = this;
    // 监听切换后需要重新计算列表高度 后续可以用activated生命周期替换
    window.addEventListener('message', (event:any)=> {
      const {action, data} = event.data;
      if (action == 'shb.frame.activatedPage'){
        that_.$nextTick(()=> {
          that_.knowTableContainerHeight();
        })
      }
    });
    this.$nextTick(()=> {
      this.knowTableContainerHeight()
      window.onresize = _.debounce(()=>{
        that_.knowTableContainerHeight()
      }, 500)
    })
  }

  public packUp = true
  /**
   * @description: 渲染头部容器
   * @return {VNode}
   */ 
  public renderHeaderContainer(): VNode {
    return (
      <div ref="tableHeaderContainer" class='header-container'>
        <div class='common-list-header__v2'>
          <div class="search-container">
            { this.renderSearchContainer() }
          </div>
          { this.renderAdvancedSearchButton(false) }
        </div>
        
        {this.isBgiSaas ? <div class="task-type-filter">
          <div class="task-list-header-nav">
            <div class="task-filter-item">
              <div class="task-font14 task-c7 state">{i18n.t('task.taskStatus')}：</div>
              <div class="list">
                <div class="list-item task-flex task-ai">
                  { this.taskStatus.map((item:any) => { return this.renderTaskStatusItem(item) }) }
                </div>
              </div>
            </div>
          </div>
        </div> : null}
        
        {this.packUp?<div class="task-type-filter">
          <div class="task-list-header-nav">
            <div class="task-filter-item">
              <div class="task-font14 task-c7 state">{i18n.t('common.task.taskType')}：</div>
              <div class="list" >
                <div class="list-item task-flex task-ai">
                  {[...[{name:i18n.t('common.base.all'),id:undefined}],...this.readTypeList].map((item:any)=>{
                    return (item.id == this.currentTaskType?.id )?<div class="task-nav-create task-c2 task-padding-0" onClick={() => this.changeTaskType(item)}>
                      <div class="actived" title={item.name}>{item.name}</div>
                    </div>: <div class="task-nav-create" onClick={() => this.changeTaskType(item)}>
                      <span title={item.name}>{item.name}</span>
                    </div>
                  })}
                </div>
              </div>
            </div>
          </div>
          </div>:null}
          <div class="pack-up">
            <div onClick={() => this.changePackUpLocal()}>
              {this.packUp?<i class="iconfont icon-Icon_up"></i>:<i class="iconfont icon-more" ></i>}
            </div>
          </div>
      </div>  
    )
  }
  
  /**
   * @description: 渲染任务状态
   * @return {VNode}
   */
  public renderTaskStatusItem(item: TaskStatus) {
    // 是否为当前选中状态
    const isActive = this.currentTaskStatus?.id === item?.id

    return (
      isActive ? (
        <div class="task-nav-create task-c2 task-padding-0" onClick={() => this.changeTaskStatus(item)}>
          <div class="actived" title={item.name}>{item.name}</div>
        </div>
      ) : (
        <div class="task-nav-create" onClick={() => this.changeTaskStatus(item)}>
          <span title={item.name}>{item.name}</span>
        </div>
      )
    )
  }

  public changeTaskStatus(item: TaskStatus) {
    
    const { name, id } = item
    this.currentTaskStatus = {
      id,
      name
    }
    this.searchParams.state = id
    // 获取工单计划任务列表
    this.fetchPlanTaskTaskList()
  }

  public async changeTaskType(item:any){
    // @ts-ignore
    this.$track.clickStat(this.$track.formatParams('QUICK_SEARCH', '工单类型'));
    const {name,id}=item
    this.currentTaskType={
      id,
      name,
      templateId:id
    }
    this.searchParams.templateId = id
    // 获取工单计划任务列表
    this.fetchPlanTaskTaskList()
    this.initializeTaskTypeAllFields()
    this.refresh()
  }

  /**
   * 高级搜索
   * @param searchModel
   */
  public handleAdvancedSearch(searchModel: any = {}){
    this.advancedSearchModel = searchModel;
    this.search();
  }

  /**
   * 常用字段切换
   * @param {*} fieldName
   * @param {*} isChecked
   */
  public changeCommonUse({fieldName, isChecked}: commonUseItemType){
    const inCommonUseSet = new Set(this.inCommonUse)
    if(isChecked){
      inCommonUseSet.add(fieldName)
    }else {
      inCommonUseSet.delete(fieldName);
    }
    this.inCommonUse = Array.from(inCommonUseSet);
    const storageKey = 'advanced-search-commonUse';
    const storageData = {
      [storageKey]: this.inCommonUse
    }
    storageSet('TaskPlanTask', JSON.stringify(storageData))
  }

  /**
   * 恢复常用字段
   */
  public async recoverCommonUse(){
    try {
      const data = JSON.parse(storageGet('TaskPlanTask') || '{}');
      const storageKey = 'advanced-search-commonUse';
      this.inCommonUse = data[storageKey] || [];
    } catch (error) {
      console.error('获取常用字段 recoverCommonUse', error);
      return Promise.reject(error)
    }
  }
  
  render(h: CreateElement) {
    // 属性列表
    const attrs = this.getAttributes()
    
    return (
      <permission auth={this.planTaskOn} text={this.noPermissionText}>
        <div {...attrs}>
          {/* 企业版或者服务云企业版显示 */}
          { (isEnterpriseEdition() || hasBSCEnterpriseEdition()) && (<upgrade-to-smart-plan-dialog ref="upgradeToSmartPlanDialog"></upgrade-to-smart-plan-dialog>) }
          { this.renderHeaderContainer() }
          { this.renderOperationContainer() }
          { this.renderContentContainer() }
          { this.renderComponentsContainer() }
        </div>
      </permission>
    )
    
  }
  
}

